﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Globalization;

namespace Tilver.Common
{
    /// <summary>
    /// 字符类型定义
    /// </summary>
    [Flags]
    public enum CharsScope
    {
        All = 15,
        Letters = 6,
        LowerLetters = 2,
        Numbers = 1,
        NumbersAndLetters = 7,
        NumbersAndLowerLetters = 3,
        NumbersAndUpperLetters = 5,
        UpperLetters = 4,
        UsualChinese = 8
    }
    /// <summary>
    /// 字符串操作静态辅助类
    /// </summary>
    public static class StringUtil
    {
        #region String扩展
        private static readonly object _lockHelp = new object();
        private static Dictionary<char, int> _numeralRadixCache = null;
        /// <summary>
        /// 英文字母
        /// </summary>
        public static readonly char[] LetterChars = new char[] { 
            'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 
            'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 
            'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 
            'W', 'X', 'Y', 'Z'
         };
        /// <summary>
        /// 小写英文字母
        /// </summary>
        public static readonly char[] LowerLetterChars = new char[] { 
            'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 
            'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'
         };
        /// <summary>
        /// 数字字符
        /// </summary>
        public static readonly char[] NumberChars = new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
        /// <summary>
        /// 数字和英文字母
        /// </summary>
        public static readonly char[] NumberLetterChars = new char[] { 
            '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 
            'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 
            'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 
            'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'
         };
        /// <summary>
        /// 数字和英文字母
        /// </summary>
        public static readonly char[] NumeralRadixChars = new char[] { 
            '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 
            'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 
            'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 
            'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '+', '/'
         };
        /// <summary>
        /// 大字英文字母
        /// </summary>
        public static readonly char[] UpperLetterChars = new char[] { 
            'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 
            'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'
         };
        /// <summary>
        /// 常用汉字
        /// </summary>
        public static readonly char[] UsualChineseChars = "的一是在不了有和人这中大为上个国我以要他时来用们生到作地于出就分对成会可主发年动同工也能下过子说产种面而方后多定行学法所民得经十三之进着等部度家电力里如水化高自二理起小物现实加量都两体制机当使点从业本去把性好应开它合还因由其些然前外天政四日那社义事平形相全表间样与关各重新线内数正心反你明看原又么利比或但质气第向道命此变条只没结解问意建月公无系军很情者最立代想已通并提直题党程展五果料象员革位入常文总次品式活设及管特件长求老头基资边流路级少图山统接知较将组见计别她手角期根论运农指几九区强放决西被干做必战先回则任取据处队南给色光门即保治北造百规热领七海口东导器压志世金增争济阶油思术极交受联什认六共权收证改清己美再采转更单风切打白教速花带安场身车例真务具万每目至达走积示议声报斗完类八离华名确才科张信马节话米整空元况今集温传土许步群广石记需段研界拉林律叫且究观越织装影算低持音众书布复容儿须际商非验连断深难近矿千周委素技备半办青省列习响约支般史感劳便团往酸历市克何除消构府称太准精值号率族维划选标写存候毛亲快效斯院查江型眼王按格养易置派层片始却专状育厂京识适属圆包火住调满县局照参红细引听该铁价严".ToCharArray();

        public static Dictionary<char, int> NumeralRadixCache
        {
            get
            {
                if (_numeralRadixCache == null)
                {
                    lock (_lockHelp)
                    {
                        if (_numeralRadixCache == null)
                        {
                            _numeralRadixCache = new Dictionary<char, int>(0x40);
                            for (int i = 0; i < NumeralRadixChars.Length; i++)
                            {
                                _numeralRadixCache.Add(NumeralRadixChars[i], i);
                            }
                        }
                    }
                }
                return _numeralRadixCache;
            }
        }

        /// <summary>
        /// 获取默认值
        /// </summary>
        /// <param name="src">源字符串</param>
        /// <param name="defaultValue">默认值</param>
        /// <returns></returns>
        public static string DefaultIfNull(this string src, string defaultValue = "")
        {
            return src ?? defaultValue;
        }
        /// <summary>
        /// 截取字符并填充后缀
        /// </summary>
        /// <param name="str"></param>
        /// <param name="width">截取宽度，全角符号占2个宽度</param>
        /// <param name="sufix">后缀字符串</param>
        /// <returns></returns>
        public static string FixWidth(this string str, int width, string sufix = "")
        {
            string str2 = null;
            if (width >= (str.Length * 2))
            {
                return str;
            }
            for (int i = 0; i < str.Length; i++)
            {
                width -= GetCharWidth(str[i]);
                if (width <= 0)
                {
                    if (width == 0)
                    {
                        str2 = string.Format("{0}{1}", str.Substring(0, i + 1), sufix);
                    }
                    else if (width == -1)
                    {
                        str2 = string.Format("{0} {1}", str.Substring(0, i), sufix);
                    }
                    break;
                }
            }
            return (str2 ?? str);
        }

        public static char[] GetCharArray(CharsScope scope)
        {
            List<char> source = new List<char>();
            if (scope.HasFlag(CharsScope.Numbers))
            {
                source.AddRange(NumberChars);
            }
            if (scope.HasFlag(CharsScope.LowerLetters))
            {
                source.AddRange(LowerLetterChars);
            }
            if (scope.HasFlag(CharsScope.UpperLetters))
            {
                source.AddRange(UpperLetterChars);
            }
            if (scope.HasFlag(CharsScope.UsualChinese))
            {
                source.AddRange(UsualChineseChars);
            }
            return source.ToArray<char>();
        }
        /// <summary>
        /// 获取字符宽度，全角字符占2个宽度
        /// </summary>
        /// <param name="chr">字符</param>
        /// <returns></returns>
        public static int GetCharWidth(char chr)
        {
            if (chr >= '\x00ff')
            {
                return 2;
            }
            return 1;
        }
        /// <summary>
        /// 获取GUID字符串
        /// </summary>
        /// <returns></returns>
        public static string GetGuidString()
        {
            return Guid.NewGuid().ToString().Replace("-", "");
        }
        /// <summary>
        /// 获取字符串长度
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static int GetStringWidth(this string str)
        {
            int num = 0;
            foreach (char ch in str)
            {
                num += GetCharWidth(ch);
            }
            return num;
        }
        /// <summary>
        /// 十六进制转二进制
        /// </summary>
        /// <param name="hex"></param>
        /// <returns></returns>
        public static byte[] HexToBytes(this string hex)
        {
            if ((hex.Length % 2) != 0)
            {
                throw new ArgumentException("16进制字符串长度必须是2的倍数。", "hex");
            }
            byte[] buffer = new byte[hex.Length / 2];
            int index = 0;
            for (int i = 0; i < hex.Length; i += 2)
            {
                buffer[index] = byte.Parse(hex.Substring(i, 2), NumberStyles.AllowHexSpecifier);
                index++;
            }
            return buffer;
        }

        public static string HexToString(this string hex, Encoding encode = null)
        {
            encode = encode ?? Encoding.UTF8;
            return encode.GetString(hex.HexToBytes());
        }
        /// <summary>
        /// 是否汉字字符
        /// </summary>
        /// <param name="chr"></param>
        /// <returns></returns>
        public static bool IsChinese(char chr)
        {
            return ((chr >= '一') && (chr <= 0x9fa5));
        }
        /// <summary>
        /// 是否包含汉字
        /// </summary>
        /// <param name="text"></param>
        /// <returns></returns>
        public static bool IsChinese(string text)
        {
            foreach (char ch in text)
            {
                if (!IsChinese(ch))
                {
                    return false;
                }
            }
            return true;
        }
        /// <summary>
        /// 是否邮箱
        /// </summary>
        /// <param name="email"></param>
        /// <returns></returns>
        public static bool IsEmail(string email)
        {
            return Regex.IsMatch(email, @"^([\w-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([\w-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$");
        }
        /// <summary>
        /// 是否身份证号
        /// </summary>
        /// <param name="cardno"></param>
        /// <returns></returns>
        public static bool IsIdCardNo(string cardno)
        {
            return IdCardStruct.IsValid(cardno);
        }
        /// <summary>
        /// 是正整数
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public static bool IsInteger(string input)
        {
            return Regex.IsMatch(input, @"^-?\d+$");
        }
        /// <summary>
        /// 是否IP地址
        /// </summary>
        /// <param name="ip"></param>
        /// <returns></returns>
        public static bool IsIpAddress(string ip)
        {
            return Regex.IsMatch(ip, @"^(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])$");
        }
        /// <summary>
        /// 是否整数
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public static bool IsNegativeInteger(string input)
        {
            return Regex.IsMatch(input, "^-[0-9]*[1-9][0-9]*$");
        }

        public static bool IsNotNegativeInteger(string input)
        {
            return Regex.IsMatch(input, @"^\d+$");
        }

        public static bool IsNotNegativeNumber(string input)
        {
            return Regex.IsMatch(input, @"^\d+[.]?\d*$");
        }

        public static bool IsNotPositiveInteger(string input)
        {
            return Regex.IsMatch(input, @"^((-\d+)|(0+))$");
        }

        public static bool IsNumber(string input)
        {
            return Regex.IsMatch(input, @"^[-]?\d+[.]?\d*$");
        }

        public static bool IsPositiveInteger(string input)
        {
            return Regex.IsMatch(input, "^[0-9]*[1-9][0-9]*$");
        }

        public static bool IsPostcode(string postcode)
        {
            return Regex.IsMatch(postcode, @"[1-9]\d{5}(?!\d)");
        }

        public static bool IsTel(string tel)
        {
            return Regex.IsMatch(tel, @"(\d+-)?(\d{4}-?\d{7}|\d{3}-?\d{8}|^\d{7,8})(-\d+)?");
        }

        public static bool IsUrl(string url)
        {
            return Regex.IsMatch(url, @"http(s)?://([\w-]+\.)+[\w-]+(/[\w- ./?%&=]*)?");
        }
        /// <summary>
        /// 将十进制整数转换为指定进位制的字符串表示，如进位制位是2，8，10，16，最好使用Convert.ToString(value, toBase)方法
        /// </summary>
        /// <param name="num">十进制整数</param>
        /// <param name="radix">进位制，如：36,62</param>
        /// <returns></returns>
        public static string RadixToString(long num, int radix)
        {
            if (num == 0L)
            {
                return "0";
            }
            string str = string.Empty;
            while (num > 0L)
            {
                str = NumeralRadixChars[(int)((IntPtr)(num % ((long)radix)))] + str;
                num /= (long)radix;
            }
            return str;
        }

        public static string ReplaceWhiteSpace(this string src, char newChar, bool repeated = true)
        {
            return src.ReplaceWhiteSpace(newChar.ToString(), repeated);
        }

        public static string ReplaceWhiteSpace(this string src, string newValue, bool repeated = false)
        {
            if (string.IsNullOrEmpty(src))
            {
                return src;
            }
            int num = -2147483648;
            StringBuilder builder = new StringBuilder();
            for (int i = 0; i < src.Length; i++)
            {
                char c = src[i];
                if (char.IsWhiteSpace(c))
                {
                    if (repeated)
                    {
                        builder.Append(newValue);
                    }
                    else
                    {
                        if (num != (i - 1))
                        {
                            builder.Append(newValue);
                        }
                        num = i;
                    }
                }
                else
                {
                    builder.Append(c);
                }
            }
            return builder.ToString();
        }
        /// <summary>
        /// 将指定进位制的字符串表示转换为十进制整数，如进位制位是2，8，10，16，最好使用Convert.ToXXX(string, fromBase)方法
        /// </summary>
        /// <param name="value">指定进位制的字符串表示</param>
        /// <param name="radix"> 进位制，如：36,62</param>
        /// <returns></returns>
        public static long ToRadix(this string value, int radix)
        {
            if (string.IsNullOrEmpty(value))
            {
                return 0L;
            }
            long num = 0L;
            for (int i = 0; i < value.Length; i++)
            {
                char ch = value[i];
                num += ((long)NumeralRadixCache[ch]) * ((long)Math.Pow((double)radix, (double)((value.Length - i) - 1)));
            }
            return num;
        }
        /// <summary>
        /// 转换为二进制数据
        /// </summary>
        /// <param name="str"></param>
        /// <param name="encode"></param>
        /// <returns></returns>
        public static byte[] ToBytes(this string str, Encoding encode = null)
        {
            encode = encode ?? Encoding.UTF8;
            return encode.GetBytes(str);
        }
        /// <summary>
        /// 转换为二六进制表示的字符串
        /// </summary>
        /// <param name="str"></param>
        /// <param name="encode"></param>
        /// <returns></returns>
        public static string ToHex(this string str, Encoding encode = null)
        {
            return BitConverter.ToString(str.ToBytes(encode)).Replace("-", "");
        }
        /// <summary>
        /// 转换为逻辑型
        /// </summary>
        /// <param name="src"></param>
        /// <param name="defaultValue"></param>
        /// <returns></returns>
        public static bool ToBoolean(this string src, bool? defaultValue = null)
        {
            bool flag;
            if (!string.IsNullOrEmpty(src) && bool.TryParse(src, out flag))
            {
                return flag;
            }
            if (!defaultValue.HasValue)
            {
                throw new ArgumentException("String转换Boolean类型失败。", src);
            }
            return defaultValue.Value;
        }

        public static bool? ToBooleanN(this string src, bool? defaultValue = null, bool throwException = false)
        {
            bool? nullable = null;
            if (!string.IsNullOrEmpty(src))
            {
                bool flag;
                if (bool.TryParse(src, out flag))
                {
                    nullable = new bool?(flag);
                }
                else if (throwException)
                {
                    throw new ArgumentException("String转换Boolean类型失败。", src);
                }
            }
            if (!nullable.HasValue && defaultValue.HasValue)
            {
                nullable = new bool?(defaultValue.Value);
            }
            return nullable;
        }

        public static byte ToByte(this string src, byte? defaultValue = null)
        {
            byte num;
            if (!string.IsNullOrEmpty(src) && byte.TryParse(src, out num))
            {
                return num;
            }
            if (!defaultValue.HasValue)
            {
                throw new ArgumentException("String转换Byte类型失败。", src);
            }
            return defaultValue.Value;
        }

        public static byte? ToByteN(this string src, byte? defaultValue = null, bool throwException = false)
        {
            byte? nullable = null;
            if (!string.IsNullOrEmpty(src))
            {
                byte num;
                if (byte.TryParse(src, out num))
                {
                    nullable = new byte?(num);
                }
                else if (throwException)
                {
                    throw new ArgumentException("String转换Byte类型失败。", src);
                }
            }
            if (!nullable.HasValue && defaultValue.HasValue)
            {
                nullable = new byte?(defaultValue.Value);
            }
            return nullable;
        }

        public static char ToChar(this string src, char? defaultValue = null)
        {
            char ch;
            if (!string.IsNullOrEmpty(src) && char.TryParse(src, out ch))
            {
                return ch;
            }
            if (!defaultValue.HasValue)
            {
                throw new ArgumentException("String转换Char类型失败。", src);
            }
            return defaultValue.Value;
        }

        public static char? ToCharN(this string src, char? defaultValue = null, bool throwException = false)
        {
            char? nullable = null;
            if (!string.IsNullOrEmpty(src))
            {
                char ch;
                if (char.TryParse(src, out ch))
                {
                    nullable = new char?(ch);
                }
                else if (throwException)
                {
                    throw new ArgumentException("String转换Char类型失败。", src);
                }
            }
            if (!nullable.HasValue && defaultValue.HasValue)
            {
                nullable = new char?(defaultValue.Value);
            }
            return nullable;
        }

        public static DateTime ToDateTime(this string src, DateTime? defaultValue = null, string format = null)
        {
            DateTime minValue = DateTime.MinValue;
            if (string.IsNullOrEmpty(format))
            {
                if (!string.IsNullOrEmpty(src) && DateTime.TryParse(src, out minValue))
                {
                    return minValue;
                }
                if (!defaultValue.HasValue)
                {
                    throw new ArgumentException("String转换DateTime类型失败。", src);
                }
                return defaultValue.Value;
            }
            if (!string.IsNullOrEmpty(src) && DateTime.TryParseExact(src, format, null, DateTimeStyles.None, out minValue))
            {
                return minValue;
            }
            if (!defaultValue.HasValue)
            {
                throw new ArgumentException("String转换DateTime类型失败。", src);
            }
            return defaultValue.Value;
        }

        public static DateTime? ToDateTimeN(this string src, DateTime? defaultValue = null, string format = null, bool throwException = false)
        {
            DateTime? nullable = null;
            if (!string.IsNullOrEmpty(src))
            {
                DateTime time;
                if (string.IsNullOrEmpty(format))
                {
                    if (!DateTime.TryParse(src, out time))
                    {
                        if (throwException)
                        {
                            throw new ArgumentException("String转换DateTime类型失败。", src);
                        }
                    }
                    else
                    {
                        nullable = new DateTime?(time);
                    }
                }
                else if (DateTime.TryParseExact(src, format, null, DateTimeStyles.None, out time))
                {
                    nullable = new DateTime?(time);
                }
                else if (throwException)
                {
                    throw new ArgumentException("String转换DateTime类型失败。", src);
                }
            }
            if (!nullable.HasValue && defaultValue.HasValue)
            {
                nullable = new DateTime?(defaultValue.Value);
            }
            return nullable;
        }

        public static decimal ToDecimal(this string src, decimal? defaultValue = null)
        {
            decimal num;
            if (!string.IsNullOrEmpty(src) && decimal.TryParse(src, out num))
            {
                return num;
            }
            if (!defaultValue.HasValue)
            {
                throw new ArgumentException("String转换Decimal类型失败。", src);
            }
            return defaultValue.Value;
        }

        public static decimal? ToDecimalN(this string src, decimal? defaultValue = null, bool throwException = false)
        {
            decimal? nullable = null;
            if (!string.IsNullOrEmpty(src))
            {
                decimal num;
                if (decimal.TryParse(src, out num))
                {
                    nullable = new decimal?(num);
                }
                else if (throwException)
                {
                    throw new ArgumentException("String转换Decimal类型失败。", src);
                }
            }
            if (!nullable.HasValue && defaultValue.HasValue)
            {
                nullable = new decimal?(defaultValue.Value);
            }
            return nullable;
        }

        public static double ToDouble(this string src, double? defaultValue = null)
        {
            double num;
            if (!string.IsNullOrEmpty(src) && double.TryParse(src, out num))
            {
                return num;
            }
            if (!defaultValue.HasValue)
            {
                throw new ArgumentException("String转换Double类型失败。", src);
            }
            return defaultValue.Value;
        }

        public static double? ToDoubleN(this string src, double? defaultValue = null, bool throwException = false)
        {
            double? nullable = null;
            if (!string.IsNullOrEmpty(src))
            {
                double num;
                if (double.TryParse(src, out num))
                {
                    nullable = new double?(num);
                }
                else if (throwException)
                {
                    throw new ArgumentException("String转换Double类型失败。", src);
                }
            }
            if (!nullable.HasValue && defaultValue.HasValue)
            {
                nullable = new double?(defaultValue.Value);
            }
            return nullable;
        }

        public static T ToEnum<T>(this string src, T? defaultValue = null) where T : struct
        {
            T local = default(T);
            if (string.IsNullOrEmpty(src))
            {
                if (!defaultValue.HasValue)
                {
                    throw new ArgumentException("String转换Enum类型失败，字符串不能为Null或空。", src);
                }
                return defaultValue.Value;
            }
            Type enumType = typeof(T);
            if (!enumType.IsEnum)
            {
                throw new ArgumentException("T 必须是一个Enum类型。");
            }
            try
            {
                local = (T)Enum.Parse(enumType, src, true);
            }
            catch
            {
                if (!defaultValue.HasValue)
                {
                    throw new ArgumentException("String转换Enum类型失败，字符串内容不正确。", src);
                }
                return defaultValue.Value;
            }
            return local;
        }

        public static T? ToEnumN<T>(this string src, T? defaultValue = null, bool throwException = false) where T : struct
        {
            T? nullable = null;
            if (!string.IsNullOrEmpty(src))
            {
                Type enumType = typeof(T);
                if (!enumType.IsEnum)
                {
                    throw new ArgumentException("T 必须是一个Enum类型。");
                }
                try
                {
                    nullable = new T?((T)Enum.Parse(enumType, src, true));
                }
                catch
                {
                    if (throwException)
                    {
                        throw new ArgumentException("String转换Enum类型失败。", src);
                    }
                }
            }
            if (!nullable.HasValue && defaultValue.HasValue)
            {
                nullable = new T?(defaultValue.Value);
            }
            return nullable;
        }

        public static short ToInt16(this string src, short? defaultValue = null)
        {
            short num;
            if (!string.IsNullOrEmpty(src) && short.TryParse(src, out num))
            {
                return num;
            }
            if (!defaultValue.HasValue)
            {
                throw new ArgumentException("String转换Int16类型失败。", src);
            }
            return defaultValue.Value;
        }

        public static short? ToInt16N(this string src, short? defaultValue = null, bool throwException = false)
        {
            short? nullable = null;
            if (!string.IsNullOrEmpty(src))
            {
                short num;
                if (short.TryParse(src, out num))
                {
                    nullable = new short?(num);
                }
                else if (throwException)
                {
                    throw new ArgumentException("String转换Int16类型失败。", src);
                }
            }
            if (!nullable.HasValue && defaultValue.HasValue)
            {
                nullable = new short?(defaultValue.Value);
            }
            return nullable;
        }

        public static int ToInt32(this string src, int? defaultValue = null)
        {
            int num;
            if (!string.IsNullOrEmpty(src) && int.TryParse(src, out num))
            {
                return num;
            }
            if (!defaultValue.HasValue)
            {
                throw new ArgumentException("String转换Int32类型失败。", src);
            }
            return defaultValue.Value;
        }

        public static int? ToInt32N(this string src, int? defaultValue = null, bool throwException = false)
        {
            int? nullable = null;
            if (!string.IsNullOrEmpty(src))
            {
                int num;
                if (int.TryParse(src, out num))
                {
                    nullable = new int?(num);
                }
                else if (throwException)
                {
                    throw new ArgumentException("String转换Int32类型失败。", src);
                }
            }
            if (!nullable.HasValue && defaultValue.HasValue)
            {
                nullable = new int?(defaultValue.Value);
            }
            return nullable;
        }

        public static long ToInt64(this string src, long? defaultValue = null)
        {
            long num;
            if (!string.IsNullOrEmpty(src) && long.TryParse(src, out num))
            {
                return num;
            }
            if (!defaultValue.HasValue)
            {
                throw new ArgumentException("String转换Int64类型失败。", src);
            }
            return defaultValue.Value;
        }

        public static long? ToInt64N(this string src, long? defaultValue = null, bool throwException = false)
        {
            long? nullable = null;
            if (!string.IsNullOrEmpty(src))
            {
                long num;
                if (long.TryParse(src, out num))
                {
                    nullable = new long?(num);
                }
                else if (throwException)
                {
                    throw new ArgumentException("String转换Int64类型失败。", src);
                }
            }
            if (!nullable.HasValue && defaultValue.HasValue)
            {
                nullable = new long?(defaultValue.Value);
            }
            return nullable;
        }

        public static sbyte ToSByte(this string src, sbyte? defaultValue = null)
        {
            sbyte num;
            if (!string.IsNullOrEmpty(src) && sbyte.TryParse(src, out num))
            {
                return num;
            }
            if (!defaultValue.HasValue)
            {
                throw new ArgumentException("String转换SByte类型失败。", src);
            }
            return defaultValue.Value;
        }

        public static sbyte? ToSByteN(this string src, sbyte? defaultValue = null, bool throwException = false)
        {
            sbyte? nullable = null;
            if (!string.IsNullOrEmpty(src))
            {
                sbyte num;
                if (sbyte.TryParse(src, out num))
                {
                    nullable = new sbyte?(num);
                }
                else if (throwException)
                {
                    throw new ArgumentException("String转换SByte类型失败。", src);
                }
            }
            if (!nullable.HasValue && defaultValue.HasValue)
            {
                nullable = new sbyte?(defaultValue.Value);
            }
            return nullable;
        }

        public static float ToSingle(this string src, float? defaultValue = null)
        {
            float num;
            if (!string.IsNullOrEmpty(src) && float.TryParse(src, out num))
            {
                return num;
            }
            if (!defaultValue.HasValue)
            {
                throw new ArgumentException("String转换Single类型失败。", src);
            }
            return defaultValue.Value;
        }

        public static float? ToSingleN(this string src, float? defaultValue = null, bool throwException = false)
        {
            float? nullable = null;
            if (!string.IsNullOrEmpty(src))
            {
                float num;
                if (float.TryParse(src, out num))
                {
                    nullable = new float?(num);
                }
                else if (throwException)
                {
                    throw new ArgumentException("String转换Single类型失败。", src);
                }
            }
            if (!nullable.HasValue && defaultValue.HasValue)
            {
                nullable = new float?(defaultValue.Value);
            }
            return nullable;
        }


        public static ushort ToUInt16(this string src, ushort? defaultValue = null)
        {
            ushort num;
            if (!string.IsNullOrEmpty(src) && ushort.TryParse(src, out num))
            {
                return num;
            }
            if (!defaultValue.HasValue)
            {
                throw new ArgumentException("String转换UInt16类型失败。", src);
            }
            return defaultValue.Value;
        }

        public static ushort? ToUInt16N(this string src, ushort? defaultValue =null, bool throwException = false)
        {
            ushort? nullable = null;
            if (!string.IsNullOrEmpty(src))
            {
                ushort num;
                if (ushort.TryParse(src, out num))
                {
                    nullable = new ushort?(num);
                }
                else if (throwException)
                {
                    throw new ArgumentException("String转换UInt16类型失败。", src);
                }
            }
            if (!nullable.HasValue && defaultValue.HasValue)
            {
                nullable = new ushort?(defaultValue.Value);
            }
            return nullable;
        }

        public static uint ToUInt32(this string src, uint? defaultValue =null)
        {
            uint num;
            if (!string.IsNullOrEmpty(src) && uint.TryParse(src, out num))
            {
                return num;
            }
            if (!defaultValue.HasValue)
            {
                throw new ArgumentException("String转换UInt32类型失败。", src);
            }
            return defaultValue.Value;
        }

        public static uint? ToUInt32N(this string src, uint? defaultValue =null, bool throwException = false)
        {
            uint? nullable = null;
            if (!string.IsNullOrEmpty(src))
            {
                uint num;
                if (uint.TryParse(src, out num))
                {
                    nullable = new uint?(num);
                }
                else if (throwException)
                {
                    throw new ArgumentException("String转换UInt32类型失败。", src);
                }
            }
            if (!nullable.HasValue && defaultValue.HasValue)
            {
                nullable = new uint?(defaultValue.Value);
            }
            return nullable;
        }

        public static ulong ToUInt64(this string src, ulong? defaultValue = null)
        {
            ulong num;
            if (!string.IsNullOrEmpty(src) && ulong.TryParse(src, out num))
            {
                return num;
            }
            if (!defaultValue.HasValue)
            {
                throw new ArgumentException("String转换UInt64类型失败。", src);
            }
            return defaultValue.Value;
        }

        public static ulong? ToUInt64N(this string src, ulong? defaultValue = null, bool throwException = false)
        {
            ulong? nullable = null;
            if (!string.IsNullOrEmpty(src))
            {
                ulong num;
                if (ulong.TryParse(src, out num))
                {
                    nullable = new ulong?(num);
                }
                else if (throwException)
                {
                    throw new ArgumentException("String转换UInt64类型失败。", src);
                }
            }
            if (!nullable.HasValue && defaultValue.HasValue)
            {
                nullable = new ulong?(defaultValue.Value);
            }
            return nullable;
        }

        

        #endregion
    }
}
